package cn.st4rlight.util.response

import cn.st4rlight.util.page.PageResult
import cn.st4rlight.util.time.DateTimes

/**
 * Restful接口统一返回值
 *
 * @author st4rlight <st4rlight@163.com>
 * Created on 2024-05-05
 */
class Message<T> private constructor(
    val code: Int,                  // 状态码
    val message: String,            // 状态描述
    val data: T? = null,            // 实际返回的数据
    val pageNo: Int? = null,
    val pageSize: Int? = null,
    val totalPage: Int? = null,
    val totalCount: Int? = null,
    val host: String ? = null,
    val port: Int ? = null,
    val timestamp: DateTimes = DateTimes.now(),
    val traceId: String ? = null
) {

    private constructor(
        result: ResultCode,
        message: String? = null,
        data: T? = null,
        pageNo: Int? = null,
        pageSize: Int? = null,
        totalPage: Int? = null,
        totalCount: Int? = null
    ) : this (
        result.code, message ?: result.msg, data, pageNo, pageSize, totalPage, totalCount
    )

    companion object {

        @JvmStatic
        fun <T> ok(): Message<T> {
            return Message(result = ResultCode.SUCCESS)
        }

        @JvmStatic
        fun <T> ok(data: T?): Message<T> {
            return Message(
                result = ResultCode.SUCCESS,
                data = data
            )
        }

        @JvmStatic
        fun <T> ok(pageResult: PageResult<T>): Message<List<T>> {
            return Message(
                result = ResultCode.SUCCESS,
                data = pageResult.data,
                pageNo = pageResult.pageNo,
                pageSize = pageResult.pageSize,
                totalPage = pageResult.countTotalPage(),
                totalCount = pageResult.totalCount
            )
        }

        @JvmStatic
        fun <T> error(result: ResultCode): Message<T> {
            return Message(result = result);
        }

        @JvmStatic
        fun <T> error(result: ResultCode, message: String): Message<T> {
            return Message(result = result, message = message);
        }

        @JvmStatic
        fun <T> error(result: Int, message: String): Message<T> {
            return Message(code = result, message = message);
        }
    }
}